﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Mesuro.Common;
using Mesuro.Graphing;

namespace Mesuro.GUI {
	/// <summary>
	/// Interaction logic for FilterDesigner.xaml
	/// </summary>
	public partial class FilterDesigner : ItemsControl {

		#region DP: AvailableChannels
		public static readonly DependencyProperty AvailableChannelsProperty = DependencyProperty.RegisterAttached( "AvailableChannels", typeof( IEnumerable<IChannelRef> ), typeof( FilterDesigner ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, AvailableChannelsChangedStatic ) );
		public IEnumerable<IChannelRef> AvailableChannels {
			get { return (IEnumerable<IChannelRef>)GetValue( AvailableChannelsProperty ); }
			set { SetValue( AvailableChannelsProperty, value ); }
		}
		public static IEnumerable<IChannelRef> GetAvailableChannels( DependencyObject element ) { return (IEnumerable<IChannelRef>)element.GetValue( AvailableChannelsProperty ); }
		public static void SetAvailableChannels( DependencyObject element, IEnumerable<IChannelRef> value ) { element.SetValue( AvailableChannelsProperty, value ); }
		private static void AvailableChannelsChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) { }
		#endregion

		#region DP: Plot
		public static readonly DependencyProperty PlotProperty = DependencyProperty.RegisterAttached( "Plot", typeof( Plot ), typeof( FilterDesigner ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, PlotChangedStatic ) );
		public Plot Plot {
			get { return (Plot)GetValue( PlotProperty ); }
			set { SetValue( PlotProperty, value ); }
		}
		public static Plot GetPlot( DependencyObject element ) { return (Plot)element.GetValue( PlotProperty ); }
		public static void SetPlot( DependencyObject element, Plot value ) { element.SetValue( PlotProperty, value ); }
		private static void PlotChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) {
			FilterDesigner fd = sender as FilterDesigner;
			if (fd != null)
				fd.OnPlotChanged( (Plot)e.OldValue, (Plot)e.NewValue );
		}
		#endregion

		#region DP: FilterBuilder (Attached Only)
		public static readonly DependencyProperty FilterBuilderProperty = DependencyProperty.RegisterAttached( "FilterBuilder", typeof( FilterBuilder ), typeof( FilterDesigner ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, FilterBuilderChangedStatic ) );
		public static FilterBuilder GetFilterBuilder( DependencyObject element ) { return (FilterBuilder)element.GetValue( FilterBuilderProperty ); }
		public static void SetFilterBuilder( DependencyObject element, FilterBuilder value ) { element.SetValue( FilterBuilderProperty, value ); }
		private static void FilterBuilderChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) { }
		#endregion

		#region DP: TransformMarker (Attached Only)
		public static readonly DependencyProperty TransformMarkerProperty = DependencyProperty.RegisterAttached( "TransformMarker", typeof( SeriesTransformCollection.TransformCollectionMarker ), typeof( FilterDesigner ), new FrameworkPropertyMetadata( null, FrameworkPropertyMetadataOptions.None, TransformMarkerChangedStatic ) );
		public static SeriesTransformCollection.TransformCollectionMarker GetTransformMarker( DependencyObject element ) { return (SeriesTransformCollection.TransformCollectionMarker)element.GetValue( TransformMarkerProperty ); }
		public static void SetTransformMarker( DependencyObject element, SeriesTransformCollection.TransformCollectionMarker value ) { element.SetValue( TransformMarkerProperty, value ); }
		private static void TransformMarkerChangedStatic( DependencyObject sender, DependencyPropertyChangedEventArgs e ) { }
		#endregion

		public FilterDesigner() {
			InitializeComponent();
			SetBinding( ItemsSourceProperty, new Binding( "Plot.(GUI:FilterDesigner.FilterBuilder).List" ) { Source = this } );
		}

		private void _compile() {

			SeriesTransformCollection.TransformCollectionMarker mkr = GetTransformMarker( Plot );

			SetTransformMarker( Plot, Plot.FilterTransform.Replace( mkr, GetFilterBuilder( Plot ).Compile() ) );

		}

		public virtual void OnPlotChanged( Plot oldValue, Plot newValue ) {
			if (newValue != null) {
				FilterBuilder fb = GetFilterBuilder( newValue );
				if (fb == null)
					SetFilterBuilder( newValue, fb = new FilterBuilder() );
				AvailableChannels = DataSet.AllChannels;
			} else {
				ItemsSource = null;
			}
		}

		private void btnAdd_Click( object sender, RoutedEventArgs e ) {
			GetFilterBuilder( Plot ).List.Add( new FilterBuilderElement() );
		}

		private void Compile_Click( object sender, RoutedEventArgs e ) {
			_compile();
		}

		private void cmdDelete_Executed( object sender, ExecutedRoutedEventArgs e ) {
			GetFilterBuilder( Plot ).List.Remove( e.Parameter as FilterBuilderElement );
		}
	}
}
